package com.jrx.anytxn.customer.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jrx.anytxn.common.constant.Constants;
import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.exception.TxnBadGatewayException;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.exception.TxnException;
import com.jrx.anytxn.common.uitl.BeanMapping;
import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.common.uitl.InternetUtils;
import com.jrx.anytxn.common.uitl.JsonUtils;
import com.jrx.anytxn.common.uitl.SeqUtils;
import com.jrx.anytxn.common.uitl.StringUtils;
import com.jrx.anytxn.customer.bean.CustomerInfoCreationBean;
import com.jrx.anytxn.customer.bean.MarketingRecordCreationBean;
import com.jrx.anytxn.customer.constant.CustomerConstant;
import com.jrx.anytxn.customer.constant.ErrorMsgConstant;
import com.jrx.anytxn.customer.dto.BaseApiReq;
import com.jrx.anytxn.customer.dto.customer.AddressInfoRes;
import com.jrx.anytxn.customer.dto.customer.CompanyInfoRes;
import com.jrx.anytxn.customer.dto.customer.ContactInfoRes;
import com.jrx.anytxn.customer.dto.customer.CusExtInfoReq;
import com.jrx.anytxn.customer.dto.customer.CustomerBaseInfoRes;
import com.jrx.anytxn.customer.dto.customer.CustomerFirstLevelRes;
import com.jrx.anytxn.customer.dto.customer.CustomerFirstLeverQueryReq;
import com.jrx.anytxn.customer.dto.customer.CustomerMobileUpdateByCmsReq;
import com.jrx.anytxn.customer.dto.customer.CustomerPageRes;
import com.jrx.anytxn.customer.dto.customer.CustomerRes;
import com.jrx.anytxn.customer.dto.customer.CustomerSecondLevelRes;
import com.jrx.anytxn.customer.dto.customer.CustomerWholeInfoRes;
import com.jrx.anytxn.customer.dto.customer.ModifyCustomerGroupReq;
import com.jrx.anytxn.customer.entity.CmCustomerAddressInfo;
import com.jrx.anytxn.customer.entity.CmCustomerContactInfo;
import com.jrx.anytxn.customer.entity.CmCustomerExtInfo;
import com.jrx.anytxn.customer.entity.CmCustomerFirstLevel;
import com.jrx.anytxn.customer.entity.CmCustomerLabel;
import com.jrx.anytxn.customer.entity.CmCustomerLimitInfo;
import com.jrx.anytxn.customer.entity.CmCustomerSecondLevel;
import com.jrx.anytxn.customer.entity.TlMarketingRecord;
import com.jrx.anytxn.customer.enums.CustomerMaintenanceType;
import com.jrx.anytxn.customer.mapper.base.CmCustomerFirstLevelMapper;
import com.jrx.anytxn.customer.mapper.base.CmCustomerSecondLevelMapper;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerAddressInfoMapper;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerContactInfoMapper;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerExtInfoMapper;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerFirstLevelMapper;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerSecondLevelMapper;
import com.jrx.anytxn.customer.plugins.HistoryLog;
import com.jrx.anytxn.customer.plugins.HistoryLogHelper;
import com.jrx.anytxn.customer.service.ICustomerLabelService;
import com.jrx.anytxn.customer.service.ICustomerService;
import com.jrx.anytxn.customer.service.IDealCustGatewayService;
import com.jrx.anytxn.feign.api.request.UserInfoUpdateRequest;
import com.jrx.anytxn.feign.api.service.IUserApiService;
import com.jrx.anytxn.feign.common.GateWayPredicate;
import com.jrx.anytxn.feign.gateway.bean.ApiResponse;
import com.jrx.anytxn.feign.gateway.bean.CustomerInfo;
import com.jrx.anytxn.feign.gateway.request.CheckRequest06;
import com.jrx.anytxn.feign.gateway.request.PhoneModifyReq;
import com.jrx.anytxn.feign.gateway.response.EcifResponse01;
import com.jrx.anytxn.feign.gateway.response.EcifResponse02;
import com.jrx.anytxn.feign.gateway.service.IInnerGatewayService;
import com.jrx.anytxn.feign.transaction.request.SendSmsReq;
import com.jrx.anytxn.feign.transaction.service.IAnyTxnTransactionService;
import com.jrx.anytxn.number.exception.SegmentException;
import com.jrx.anytxn.number.service.ISegmentService;
import com.jrx.anytxn.param.constant.Constant;
import com.jrx.anytxn.param.entity.PrChannelTable;
import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.mapper.ext.ExtPrChannelTableMapper;
import com.jrx.anytxn.param.mapper.ext.ExtPrOrganizationTableMapper;
import com.jrx.anytxn.param.service.system.IChannelTableService;
import com.jrx.anytxn.param.utils.BizTypeProducts;
import com.jrx.anytxn.ribbon.config.GrayVersionConfig;
import com.jrx.anytxn.sharding.pojo.dto.UpdateCacheMapping;
import com.jrx.anytxn.sharding.pojo.entity.CacheMapping;
import com.jrx.anytxn.sharding.service.ICacheMappingService;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * @ClassName CustomerServiceImpl
 * @Description: 客户信息管理的服务实现
 * @Author liy
 * @Date 2019/7/19
 * @Version V1.0
 **/
@Service
public class CustomerServiceImpl implements ICustomerService {
    private static Logger logger = LoggerFactory.getLogger(CustomerServiceImpl.class);

    @Resource
    private CmCustomerFirstLevelMapper cmCustomerFirstLevelMapper;
    @Resource
    private ExtCmCustomerFirstLevelMapper extCmCustomerFirstLevelMapper;
    @Resource
    private CmCustomerSecondLevelMapper cmCustomerSecondLevelMapper;
    @Resource
    private ExtCmCustomerSecondLevelMapper extCmCustomerSecondLevelMapper;
    @Resource
    private ExtCmCustomerAddressInfoMapper extCmCustomerAddressInfoMapper;
    @Resource
    private ExtCmCustomerContactInfoMapper extCmCustomerContactInfoMapper;
    @Autowired(required = false)
    private ICacheMappingService cacheMappingService;
    @Lazy
    @Autowired
    private IInnerGatewayService innerGatewayService;
    @Autowired
    private IDealCustGatewayService dealCustGatewayService;
    @Resource
    private ExtPrOrganizationTableMapper extPrOrganizationTableMapper;
    @Autowired
    private IChannelTableService iChannelTableService;
    @Autowired
    ICustomerLabelService customerLabelService;
    @Autowired
    private GrayVersionConfig grayVersionConfig;
    @Autowired
    private IAnyTxnTransactionService iAnyTxnTransactionService;
    @Autowired
    private IUserApiService iUserApiService;
    @Resource
    private ExtPrChannelTableMapper extPrChannelTableMapper;
    @Resource
    private ExtCmCustomerExtInfoMapper extCmCustomerExtInfoMapper;
    @Autowired
    private ISegmentService iSegmentService;

    /**
     * 客户建档
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveInfo(CustomerInfoCreationBean customerOperationBean) throws Exception {
        try {
            HistoryLog txnHistoryLog = new HistoryLog();
            //声明渠道 用于客户一级表修改使用
            //注册ECIF
//            String ecifCustId = this.dealEcif(customerOperationBean);


            CacheMapping cacheMapping = customerOperationBean.getCacheMapping();
            //判断是否需要添加路由对像
            if (null != cacheMapping) {
                //如果存在执行添加客户二级表
                int i = cacheMappingService.addCacheMapping(cacheMapping);
                //添加路由成功
                if (i <= 0) {
                    //添加路由失败抛出异常
                    String cacheMappingError = String.format(ErrorMsgConstant.CREATE_CACHE_ERROR, cacheMapping);
                    throw new TxnBizException(cacheMappingError);
                }
            }

            CmCustomerSecondLevel saveSecond = customerOperationBean.getAddCmCustomerSecondLevel();
            if (null != saveSecond) {
                int secondAdd = cmCustomerSecondLevelMapper.insertSelective(saveSecond);
                if (secondAdd <= 0) {
                    throw new TxnBizException(ErrorMsgConstant.SECOND_CUSTOMER_ADD_ERROR);
                }
            }

            CmCustomerSecondLevel updateSecond = customerOperationBean.getModifyCmCustomerSecondLevel();
            if (null != updateSecond) {
                txnHistoryLog = new HistoryLog(updateSecond.getCustomerId(), updateSecond.getTenantId(), customerOperationBean.getOrgId(), customerOperationBean.getChannel(), updateSecond.getUpdateBy(), CustomerMaintenanceType.CUSTOMER_INFO.getCode());
                HistoryLogHelper.setLocalHistory(txnHistoryLog);
                //不存在执行修改客户二级表操作
                int secondModify = extCmCustomerSecondLevelMapper.updateByIdAndCustomerIdAndTenantId(updateSecond);
                if (secondModify <= 0) {
                    throw new TxnBizException(ErrorMsgConstant.SECOND_CUSTOMER_MODIFY_ERROR);
                }
            }

            CmCustomerFirstLevel saveFirst = customerOperationBean.getAddCmCustomerFirstLevel();
            //判断一级客户表是否存在添加数据
            if (null != saveFirst) {
//                saveFirst.setEcifId(ecifCustId);
                //存在 执行添加操作
                int firstAdd = cmCustomerFirstLevelMapper.insertSelective(saveFirst);
                if (firstAdd <= 0) {
                    throw new TxnBizException(ErrorMsgConstant.FIRST_CUSTOMER_ADD_ERROR);
                }
            }

            CmCustomerFirstLevel updateFirst = customerOperationBean.getModifyCmCustomerFirstLevel();
            //判断一级客户表是否存在修改数据
            if (null != updateFirst) {
                txnHistoryLog = new HistoryLog(updateFirst.getCustomerId(), updateFirst.getTenantId(), customerOperationBean.getOrgId(), customerOperationBean.getChannel(), updateFirst.getUpdateBy(), CustomerMaintenanceType.CUSTOMER_INFO.getCode());
                HistoryLogHelper.setLocalHistory(txnHistoryLog);
//                updateFirst.setEcifId(ecifCustId);
                //存在 执行修改操作
                int firstModify = extCmCustomerFirstLevelMapper.updateByIdAndCustomerIdAndTenantId(updateFirst);
                if (firstModify <= 0) {
                    throw new TxnBizException(ErrorMsgConstant.FIRST_CUSTOMER_MODIFY_ERROR);
                }
            }

            //修改客户地址表状态 为失效
            CmCustomerAddressInfo updateAdrInfo = new CmCustomerAddressInfo();
            updateAdrInfo.setCustomerId(customerOperationBean.getCustomerId());
            updateAdrInfo.setTenantId(customerOperationBean.getTenantId());
            updateAdrInfo.setOrganizationId(customerOperationBean.getOrgId());
            updateAdrInfo.setChannel(customerOperationBean.getChannel());
            updateAdrInfo.setAddressStatus(CustomerConstant.STATUS_FAILURE);
            extCmCustomerAddressInfoMapper.updateByCondSelective(updateAdrInfo);
            //修改客户联系人的状态 为失效
            CmCustomerContactInfo updateConInfo = new CmCustomerContactInfo();
            updateConInfo.setCustomerId(customerOperationBean.getCustomerId());
            updateConInfo.setTenantId(customerOperationBean.getTenantId());
            updateConInfo.setOrganizationId(customerOperationBean.getOrgId());
            updateConInfo.setChannel(customerOperationBean.getChannel());
            updateConInfo.setContactStatus(CustomerConstant.STATUS_FAILURE);
            extCmCustomerContactInfoMapper.updateByCondSelective(updateConInfo);


            //获取添加客户地址信息集合
            List<CmCustomerAddressInfo> addCmCustomerAddressList = customerOperationBean.getAddCmCustomerAddressList();
            if (!addCmCustomerAddressList.isEmpty()) {
                extCmCustomerAddressInfoMapper.batchInsertSelective(addCmCustomerAddressList);
            }
            //获取添加客户联系人信息集合
            List<CmCustomerContactInfo> addCmCustomerContactList = customerOperationBean.getAddCmCustomerContactList();
            if (!addCmCustomerContactList.isEmpty()) {
                extCmCustomerContactInfoMapper.batchInsertSelective(addCmCustomerContactList);
            }
            //客户标签集合
            List<CmCustomerLabel> labelList = customerOperationBean.getCustomerLabelList();
            customerLabelService.saveCustomerLabels(labelList);

        } finally {
            HistoryLogHelper.clearLocalHistory();
        }
    }


    /**
     * 处理ecif注册/更新
     *
     * @param customerOperationBean
     * @return
     * @throws Exception
     */
    private String dealEcif(CustomerInfoCreationBean customerOperationBean) throws Exception {
        String ecifCustId = customerOperationBean.getEcifCmCustomerFirstLevel().getEcifId();
        if (!customerOperationBean.getEcifUpdate().equalsIgnoreCase(CustomerConstant.ECIF_UPDATE_NO)) {
            //需要维护 ECIF客户信息
            String ecifRequest02Json = dealCustGatewayService.buildQueryEcifReq(customerOperationBean);
            GateWayPredicate<EcifResponse02> queryPred = () -> innerGatewayService.queryEcifInfo(ecifRequest02Json);
            EcifResponse02 ecifQueryResult = queryPred.getRes(queryPred);
            if (null == ecifQueryResult) {
                throw new TxnBadGatewayException(ErrorMsgConstant.GATEWAY_ERROR);
            }
            // 新增 存在跳过，不存在新增; 新增更新 存在更新，不存在新增
            if (customerOperationBean.getEcifUpdate().equalsIgnoreCase(CustomerConstant.ECIF_UPDATE_ADD) && StringUtils.isNotBlank(ecifQueryResult.getEcifNo())) {
                return ecifQueryResult.getEcifNo();
            } else {
                ecifCustId = ecifQueryResult.getEcifNo();
            }
            String ecifRequest01Json = dealCustGatewayService.buildRegistEcifReq(customerOperationBean, ecifCustId, ecifQueryResult);
            GateWayPredicate<EcifResponse01> ecifPred = () -> innerGatewayService.registerEcif(ecifRequest01Json);
            EcifResponse01 registResult = ecifPred.getRes(ecifPred);
            if (null == registResult) {
                throw new TxnBadGatewayException(ErrorMsgConstant.GATEWAY_ERROR);
            }
            ecifCustId = registResult.getEcifNo();
        }
        return ecifCustId;
    }

    /**
     * 客户注册
     *
     * @param customerOperationBean 客户建档信息 整合后处理数据库的bean
     * @throws TxnBizException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void registerInfo(CustomerInfoCreationBean customerOperationBean) throws TxnBizException {
        try {
            CacheMapping cacheMapping = customerOperationBean.getCacheMapping();
            HistoryLog txnHistoryLog = new HistoryLog();
            //判断是否需要添加路由对像
            if (null != cacheMapping) {
                //如果存在执行添加客户二级表
                int i = cacheMappingService.addCacheMapping(cacheMapping);
                //添加路由成功
                if (i <= 0) {
                    //添加路由失败抛出异常
                    String cacheMappingError = String.format(ErrorMsgConstant.CREATE_CACHE_ERROR, cacheMapping);
                    throw new TxnBizException(cacheMappingError);
                }
            }
            CmCustomerSecondLevel saveSecond = customerOperationBean.getAddCmCustomerSecondLevel();
            if (null != saveSecond) {
                int secondAdd = cmCustomerSecondLevelMapper.insertSelective(saveSecond);
                if (secondAdd <= 0) {
                    throw new TxnBizException(ErrorMsgConstant.SECOND_CUSTOMER_ADD_ERROR);
                }
            }
            CmCustomerFirstLevel saveFirst = customerOperationBean.getAddCmCustomerFirstLevel();
            //判断一级客户表是否存在添加数据
            if (null != saveFirst) {
                //存在 执行添加操作
                int firstAdd = cmCustomerFirstLevelMapper.insertSelective(saveFirst);
                if (firstAdd <= 0) {
                    throw new TxnBizException(ErrorMsgConstant.FIRST_CUSTOMER_ADD_ERROR);
                }
            }
            CmCustomerSecondLevel updateSecond = customerOperationBean.getModifyCmCustomerSecondLevel();
            if (null != updateSecond) {
                txnHistoryLog = new HistoryLog(updateSecond.getCustomerId(), updateSecond.getTenantId(), customerOperationBean.getOrgId(), customerOperationBean.getChannel(), updateSecond.getUpdateBy(), CustomerMaintenanceType.CUSTOMER_INFO.getCode());
                HistoryLogHelper.setLocalHistory(txnHistoryLog);
                //不存在执行修改客户二级表操作
                int secondModify = extCmCustomerSecondLevelMapper.updateByIdAndCustomerIdAndTenantId(updateSecond);
                if (secondModify <= 0) {
                    throw new TxnBizException(ErrorMsgConstant.SECOND_CUSTOMER_MODIFY_ERROR);
                }
            }
            CmCustomerFirstLevel updateFirst = customerOperationBean.getModifyCmCustomerFirstLevel();
            //判断一级客户表是否存在修改数据
            if (null != updateFirst) {
                txnHistoryLog = new HistoryLog(updateFirst.getCustomerId(), updateFirst.getTenantId(), customerOperationBean.getOrgId(), customerOperationBean.getChannel(), updateFirst.getUpdateBy(), CustomerMaintenanceType.CUSTOMER_INFO.getCode());
                HistoryLogHelper.setLocalHistory(txnHistoryLog);
                //存在 执行修改操作
                int firstModify = extCmCustomerFirstLevelMapper.updateByIdAndCustomerIdAndTenantId(updateFirst);
                if (firstModify <= 0) {
                    throw new TxnBizException(ErrorMsgConstant.FIRST_CUSTOMER_MODIFY_ERROR);
                }
            }
            //客户标签集合
            List<CmCustomerLabel> labelList = customerOperationBean.getCustomerLabelList();
            customerLabelService.saveCustomerLabels(labelList);
        } finally {
            HistoryLogHelper.clearLocalHistory();
        }
    }

    @Override
    public CustomerRes getCustomerByChannelAndUserId(String channel, String userId, String tenantId) throws TxnBizException {
        //获取客户二级信息
        CmCustomerSecondLevel secondLevel = getSecondLevelByCondition(userId, channel, tenantId, null);
        //获取客户一级信息
        CmCustomerFirstLevel firstLevel = getFirstLevelByCondition(secondLevel.getCustomerId(),
                secondLevel.getOrganizationId(), tenantId);
        //构建返回信息
        CustomerRes res = new CustomerRes();
        res.setFirstLevel(BeanMapping.copy(firstLevel, CustomerFirstLevelRes.class));
        res.setSecondLevel(BeanMapping.copy(secondLevel, CustomerSecondLevelRes.class));
        return res;
    }

    @Override
    public CustomerWholeInfoRes customerInfoQuery(BaseApiReq baseApiReq) throws TxnBizException {
        CustomerWholeInfoRes res = new CustomerWholeInfoRes();
        //获取客户二级信息
        CmCustomerSecondLevel secondLevel = getSecondLevelByCondition(baseApiReq.getUserId(), baseApiReq.getChannel(),
                baseApiReq.getTenantId(), null);
        //获取客户一级信息
        CmCustomerFirstLevel firstLevel = getFirstLevelByCondition(secondLevel.getCustomerId(),
                secondLevel.getOrganizationId(), baseApiReq.getTenantId());

        //获取客户地址信息
        CmCustomerAddressInfo addressCond = new CmCustomerAddressInfo();
        addressCond.setChannel(baseApiReq.getChannel());
        addressCond.setAddressStatus(CustomerConstant.STATUS_NORMAL);
        addressCond.setOrganizationId(firstLevel.getOrganizationId());
        addressCond.setCustomerId(firstLevel.getCustomerId());
        addressCond.setTenantId(baseApiReq.getTenantId());
        List<CmCustomerAddressInfo> addressInfos = extCmCustomerAddressInfoMapper.selectByCondSelective(addressCond);

        //获取联系人信息
        CmCustomerContactInfo contactInfoCond = new CmCustomerContactInfo();
        contactInfoCond.setChannel(baseApiReq.getChannel());
        contactInfoCond.setContactStatus(CustomerConstant.STATUS_NORMAL);
        contactInfoCond.setOrganizationId(firstLevel.getOrganizationId());
        contactInfoCond.setCustomerId(firstLevel.getCustomerId());
        contactInfoCond.setTenantId(baseApiReq.getTenantId());
        List<CmCustomerContactInfo> contactInfos = extCmCustomerContactInfoMapper.selectByCondSelective(contactInfoCond);
        //构建返回
        BeanMapping.copy(firstLevel, res);
        res.setBirthDate(DateUtils.format(firstLevel.getBirthDate()));
        BeanMapping.copy(secondLevel, res);
        res.setAddressInfoList(BeanMapping.copyList(addressInfos, AddressInfoRes.class));
        res.setContactInfoList(parse(contactInfos));
        res.setSeqNo(baseApiReq.getSeqNo());
        return res;
    }

    /**
     * 根据核心客户编号获取客户信息
     *
     * @param firstLeverQueryReq 请求信息
     * @return 客户一级客户信息
     */
    @Override
    public CustomerWholeInfoRes customerFirstLeverQuery(CustomerFirstLeverQueryReq firstLeverQueryReq) throws TxnBizException {
        CustomerWholeInfoRes res = new CustomerWholeInfoRes();
        //获取客户一级信息
        CmCustomerFirstLevel firstLevel = getFirstLevelByEcifId(firstLeverQueryReq.getTenantId(), firstLeverQueryReq.getEcifId());
        //获取客户二级信息
        CmCustomerSecondLevel secondLevelCond = new CmCustomerSecondLevel();
        secondLevelCond.setCustomerId(firstLevel.getCustomerId());
        secondLevelCond.setTenantId(firstLeverQueryReq.getTenantId());
        List<CmCustomerSecondLevel> secondLevels = extCmCustomerSecondLevelMapper.selectByCondition(secondLevelCond);
        if (CollectionUtils.isEmpty(secondLevels)) {
            logger.error("获取客户信息时客户二级信息不存在");
            throw new TxnBizException(TxnRespCode.CUSTOMER_INFO_NOT_EXIST.getCode(), TxnRespCode.CUSTOMER_INFO_NOT_EXIST.getMsg());
        } else if (secondLevels.size() > 1) {
            logger.error(ErrorMsgConstant.UNIQUE_SECORD_CUSTOMER);
            throw new TxnBizException(TxnRespCode.BIZ_ERROR.getCode(), TxnRespCode.BIZ_ERROR.getUserTips());
        }
        //构建返回
        BeanUtils.copyProperties(firstLevel, res);
        res.setBirthDate(DateUtils.format(firstLevel.getBirthDate()));
        res.setSeqNo(firstLeverQueryReq.getSeqNo());
        BeanUtils.copyProperties(secondLevels.get(0), res);
        return res;
    }

    /**
     * 验证身份证有效期，并尝试更新
     * @param firstLevel
     * @param nextMonthDay
     */
    @Override
    public void validIdCard(CmCustomerFirstLevel firstLevel, String nextMonthDay) {
        if (Objects.nonNull(firstLevel) && StringUtils.isNotBlank(firstLevel.getIdExpireDate())) {
            try {
                // 证件有效期终止日期
                String idExpireDate = firstLevel.getIdExpireDate();

                // 提前一个月的日期大于身份证有效期
                if (!CustomerConstant.ID_CARD_TYPE.equalsIgnoreCase(idExpireDate) && nextMonthDay.compareTo(idExpireDate) >= 0) {
                    logger.info("开始查询ecif信息");
                    CustomerInfoCreationBean customerOperationBean = new CustomerInfoCreationBean();
                    String tenantId = firstLevel.getTenantId();
                    customerOperationBean.setTenantId(tenantId);
                    customerOperationBean.setEcifCmCustomerFirstLevel(firstLevel);
                    // 查询ecif信息
                    String ecifRequest02Json = dealCustGatewayService.buildQueryEcifReq(customerOperationBean);
                    GateWayPredicate<EcifResponse02> queryPred = () -> innerGatewayService.queryEcifInfo(ecifRequest02Json);
                    EcifResponse02 ecifQueryResult = queryPred.getRes(queryPred);
                    logger.info("查询ecif修改身份证信息返回结果:{}", JSONObject.toJSONString(ecifQueryResult));
                    if (null == ecifQueryResult) {
                        throw new TxnBadGatewayException(ErrorMsgConstant.GATEWAY_ERROR);
                    }
                    CustomerInfo custInfo = ecifQueryResult.getCustInfo();
                    if (Objects.nonNull(custInfo) && Objects.nonNull(custInfo.getSourceExt()) && !custInfo.getSourceExt().isEmpty()) {
                        Map<String, String> sourceExt = custInfo.getSourceExt();
                        // 发证日期
                        String legalIssDate = "";
                        if (StringUtils.isNotBlank(sourceExt.get("LegalIssDate"))) {
                            legalIssDate = DateUtils.format(DateUtils.parseDate(sourceExt.get("LegalIssDate"), DateUtils.DATE_PATTERN_ANOTHER));
                        }
                        // 证件到期日
                        String legalExpDate = "";
                        if (StringUtils.isNotBlank(sourceExt.get("LegalExpDate"))) {
                            // 长期的需转换成2099-12-31
                            if (CustomerConstant.ID_CARD_TYPE.equalsIgnoreCase(sourceExt.get("LegalExpDate"))) {
                                legalExpDate = "2099-12-31";
                            }else{
                                legalExpDate = DateUtils.format(DateUtils.parseDate(sourceExt.get("LegalExpDate"), DateUtils.DATE_PATTERN_ANOTHER));
                            }
                        }
                        // 发证机关
                        String legalIssAuth = "";
                        if (StringUtils.isNotBlank(sourceExt.get("LegalIssAuth"))) {
                            legalIssAuth = sourceExt.get("LegalIssAuth");
                        }
                        // 当前日期小于等于证件的截止有效日期
                        String today = DateUtils.formatDate();
                        if (StringUtils.isNotBlank(legalExpDate) && StringUtils.isNotBlank(legalIssDate) &&today.compareTo(legalExpDate) < 0) {
                            logger.info("修改用户{}的身份证有效期{},{}", firstLevel.getCustomerId(), legalExpDate, legalExpDate);
                            firstLevel.setIdIssueAgent(legalIssAuth);
                            firstLevel.setIdExpireDate(legalExpDate);
                            firstLevel.setIdEffectiveDate(legalIssDate);
                            extCmCustomerFirstLevelMapper.updateByIdAndCustomerIdAndTenantId(firstLevel);
                            try {
                                // 获取自营渠道
                                List<PrChannelTable> prChannelTables = extPrChannelTableMapper.selectAllByTenIdAndPrivateChannel(tenantId, CustomerConstant.PRIVATE_CHANNEL_YES);
                                // 查询客户二级档，获取渠道为自营（渠道配置）的二级档信息，如果没有自营渠道二级档，则不处理
                                for (PrChannelTable channelTable : prChannelTables) {
                                    CmCustomerSecondLevel cmCustomerSecondLevel = extCmCustomerSecondLevelMapper.selectByCustomerIdAndChannel(firstLevel.getCustomerId(), channelTable.getChannelId(), tenantId);
                                    if (Objects.nonNull(cmCustomerSecondLevel)) {
                                        UserInfoUpdateRequest request = new UserInfoUpdateRequest();
                                        request.setTenantId(tenantId);
                                        request.setUserId(cmCustomerSecondLevel.getUserId());
                                        request.setChannelNo(cmCustomerSecondLevel.getChannel());
                                        request.setReqId(CustomerConstant.GATEWAY_SERVICE_ID);
                                        request.setName(firstLevel.getChineseName());
                                        request.setCertNo(firstLevel.getIdNumber());
                                        request.setIssuedBy(legalIssAuth);
                                        request.setIdExpireDate(legalExpDate.replaceAll("-", ""));
                                        request.setIdEffectiveDate(legalIssDate.replaceAll("-", ""));
                                        iUserApiService.updateCustomerInfo(JsonUtils.toJSon(request));
                                    }
                                }
                            } catch (Exception e) {
                                logger.warn("更新api用户信息出错了:{}", e.getMessage());
                                e.printStackTrace();
                            }

                        }
                    }
                }
            } catch (Exception e) {
                logger.warn("验证身份证有效期失败:{}", e.getMessage());
            }
        }
    }

    /**
     * 验证身份证有效期
     *
     * @param baseApiReq
     * @return
     */
    @Override
    public CustomerWholeInfoRes validCard(BaseApiReq baseApiReq) throws TxnBizException {
        CustomerWholeInfoRes res = new CustomerWholeInfoRes();
        //获取客户二级信息
        CmCustomerSecondLevel secondLevel = getSecondLevelByCondition(baseApiReq.getUserId(), baseApiReq.getChannel(),
                baseApiReq.getTenantId(), null);
        //获取客户一级信息
        CmCustomerFirstLevel firstLevel = getFirstLevelByCondition(secondLevel.getCustomerId(),
                secondLevel.getOrganizationId(), baseApiReq.getTenantId());
        // 0.无效、1.有效
        String idExpireDate = firstLevel.getIdExpireDate();
        String currentDay = DateUtils.formatDate();
        // 验证身份证有效期，并尝试更新
        if (!CustomerConstant.ID_CARD_TYPE.equalsIgnoreCase(idExpireDate) && currentDay.compareTo(idExpireDate) > 0) {
            // 当前日期提前一个月
            String nextMonthDay = DateUtils.format(DateUtils.addMonth(new Date(), 1));
            this.validIdCard(firstLevel, nextMonthDay);
            // 更改后的有效期
            idExpireDate = firstLevel.getIdExpireDate();
        }
        // 当前日期
        if (!CustomerConstant.ID_CARD_TYPE.equalsIgnoreCase(idExpireDate) && currentDay.compareTo(idExpireDate) > 0) {
            // 已经失效，需要发送短息提醒
            String customerId = firstLevel.getCustomerId();
            SendSmsReq req = new SendSmsReq();
            // 身份证有效期短信
            CmCustomerSecondLevel customerSecondLevel = this.getSecondByChannelAndCustomerIdAndTensnId(Constants.DEFAULT_CHANNEL, customerId, Constants.DEFAULT_TENANT_ID, null);
            if (null != customerSecondLevel) {
                logger.info("----组装证件失效提醒发送短信的必要参数----");
                req.setChannel(customerSecondLevel.getChannel());
                req.setTenantId(customerSecondLevel.getTenantId());
                req.setMobile(customerSecondLevel.getMobile());
                req.setSeqNo(SeqUtils.getRandomNumber(18));
                req.setSmsType(CustomerConstant.SMS_TYPE_ID_INVALID);
                req.setCustomerId(customerSecondLevel.getCustomerId());
                iAnyTxnTransactionService.sendSms(req);
            }
        }
        BeanMapping.copy(firstLevel, res);
        res.setBirthDate(DateUtils.format(firstLevel.getBirthDate()));
        BeanMapping.copy(secondLevel, res);
        return res;
    }


    @Override
    public CustomerSecondLevelRes getByUserIdAndChannel(String userId, String channel, String tenantId) throws TxnBizException {
        CacheMapping cacheMapping = cacheMappingService.selectByUserIdAndChannel(tenantId, userId, channel);

        if (cacheMapping == null) {
            logger.error("未发现客户路由信息 userId:{} ",userId);
            throw new TxnBizException(TxnRespCode.NO_DATA.getCode(), TxnRespCode.NO_DATA.getMsg());
        }
        if (StringUtils.isBlank(userId) && StringUtils.isBlank(channel)) {
            throw new TxnBizException(TxnRespCode.NOT_EMPTY.getCode(), TxnRespCode.NOT_EMPTY.getUserTips());
        }
        CmCustomerSecondLevel cmCustomerSecondLevel = extCmCustomerSecondLevelMapper.selectByUserIdAndChannel(userId, channel, tenantId);
        if (cmCustomerSecondLevel == null) {
            throw new TxnBizException(TxnRespCode.NO_DATA.getCode(), TxnRespCode.NO_DATA.getMsg());
        }
        return BeanMapping.copy(cmCustomerSecondLevel, CustomerSecondLevelRes.class);
    }


    @Override
    public void editByUserIdAndOrgIdAndChannel(String customerId, String organizationId, String channel, Integer statementDd, String tenantId) throws TxnBizException {
        int count = extCmCustomerSecondLevelMapper.updateStatementDd(customerId, organizationId, channel, statementDd,
                tenantId);
      /*  if (count != 1) {
            String errMsg = String.format(ErrorMsgConstant.MODIFY_CUSTOMER_STATEMENT_ERROR, customerId, channel);
            logger.error(errMsg);
            throw new TxnBizException(TxnRespCode.BIZ_ERROR.getCode(), errMsg);
        }*/
    }

    @Override
    public void editPaymentDd(String customerId, String organizationId, String channel, Integer paymentDd, String tenantId) throws TxnBizException {
        extCmCustomerSecondLevelMapper.updatePaymentDd(customerId, organizationId, channel, paymentDd,
                tenantId);
      /*  if (count != 1) {
            String errMsg = String.format(ErrorMsgConstant.MODIFY_CUSTOMER_STATEMENT_ERROR, customerId, channel);
            logger.error(errMsg);
            throw new TxnBizException(TxnRespCode.BIZ_ERROR.getCode(), errMsg);
        }*/
    }

    @Override
    public CmCustomerFirstLevel getFirstLevelByCondition(String customerId, String organizationId, String tenantId) throws TxnBizException {
        CmCustomerFirstLevel firstLevelCond = new CmCustomerFirstLevel();
        firstLevelCond.setCustomerId(customerId);
        firstLevelCond.setOrganizationId(organizationId);
        firstLevelCond.setTenantId(tenantId);
        List<CmCustomerFirstLevel> firstLevels = extCmCustomerFirstLevelMapper.selectByCondition(firstLevelCond);
        if (firstLevels == null || firstLevels.isEmpty()) {
            logger.error("获取客户信息时客户一级信息不存在, customerId: {}", customerId);
            throw new TxnBizException(TxnRespCode.CUSTOMER_INFO_NOT_EXIST.getCode(), TxnRespCode.CUSTOMER_INFO_NOT_EXIST.getMsg());
        } else if (firstLevels.size() > 1) {
            logger.error(ErrorMsgConstant.UNIQUE_FIRST_CUSTOMER);
            throw new TxnBizException(TxnRespCode.BIZ_ERROR.getCode(), TxnRespCode.BIZ_ERROR.getUserTips());
        }
        return firstLevels.get(0);
    }

    /**
     * 根据核心客户编号获取一级客户信息
     * 内部调用使用 禁止controller直接调用
     *
     * @param tenantId 租户id
     * @param ecifId   机构信息
     * @return 一级信息
     * @throws TxnBizException 自定义异常
     */
    @Override
    public CmCustomerFirstLevel getFirstLevelByEcifId(String tenantId, String ecifId) throws TxnBizException {
        CmCustomerFirstLevel firstLevelCond = new CmCustomerFirstLevel();
        firstLevelCond.setEcifId(ecifId);
        firstLevelCond.setTenantId(tenantId);
        List<CmCustomerFirstLevel> firstLevels = extCmCustomerFirstLevelMapper.selectByCondition(firstLevelCond);
        if (firstLevels == null || firstLevels.isEmpty()) {
            logger.error("获取客户信息时客户一级信息不存在, ecifId: {}", ecifId);
            throw new TxnBizException(TxnRespCode.CUSTOMER_INFO_NOT_EXIST.getCode(), TxnRespCode.CUSTOMER_INFO_NOT_EXIST.getMsg());
        } else if (firstLevels.size() > 1) {
            logger.error(ErrorMsgConstant.UNIQUE_FIRST_CUSTOMER);
            throw new TxnBizException(TxnRespCode.BIZ_ERROR.getCode(), TxnRespCode.BIZ_ERROR.getUserTips());
        }
        return firstLevels.get(0);
    }

    @Override
    public CmCustomerFirstLevel getFirstLevelByCondition(String customerId, String organizationId, String tenantId, String idType, String idNo) {
        CmCustomerFirstLevel firstLevelCond = new CmCustomerFirstLevel();
        firstLevelCond.setCustomerId(customerId);
        firstLevelCond.setOrganizationId(organizationId);
        firstLevelCond.setTenantId(tenantId);
        firstLevelCond.setIdType(idType);
        firstLevelCond.setIdNumber(idNo);
        CmCustomerFirstLevel firstLevel = extCmCustomerFirstLevelMapper.selectFirstLevelByOrgIdAndId(idNo, idType, organizationId, tenantId, customerId);
        return firstLevel;
    }

    @Override
    public CmCustomerSecondLevel getSecondLevelByCondition(String userId, String channel, String tenantId, String productId) throws TxnBizException {

        CmCustomerSecondLevel secondLevelCond = new CmCustomerSecondLevel();
        secondLevelCond.setChannel(channel);
        secondLevelCond.setUserId(userId);
        secondLevelCond.setTenantId(tenantId);

        List<CmCustomerSecondLevel> secondLevels = extCmCustomerSecondLevelMapper.selectByCondition(secondLevelCond);

        if (CollectionUtils.isEmpty(secondLevels)) {
            logger.error("获取客户信息时客户二级信息不存在");
            throw new TxnBizException(TxnRespCode.CUSTOMER_INFO_NOT_EXIST.getCode(), TxnRespCode.CUSTOMER_INFO_NOT_EXIST.getMsg());
        } else if (secondLevels.size() > 1) {
            logger.error(ErrorMsgConstant.UNIQUE_SECORD_CUSTOMER);
            throw new TxnBizException(TxnRespCode.BIZ_ERROR.getCode(), TxnRespCode.BIZ_ERROR.getUserTips());
        }
        CmCustomerSecondLevel secondLevel = setOrgAndMgrNo(tenantId, productId, secondLevels);
        return secondLevel;
    }

    /**
     * 客户联系人转换
     *
     * @param contactInfos 联系人信息
     * @return 联系人信息
     */
    private List<ContactInfoRes> parse(List<CmCustomerContactInfo> contactInfos) {
        if (contactInfos == null || contactInfos.isEmpty()) {
            return new ArrayList<>();
        }
        List<ContactInfoRes> ls = new ArrayList<>(contactInfos.size());
        ContactInfoRes contactInfoRes;
        for (CmCustomerContactInfo contactInfo : contactInfos) {
            contactInfoRes = BeanMapping.copy(contactInfo, ContactInfoRes.class);
            contactInfoRes.setIncome(contactInfo.getIncome() == null ? "" : String.valueOf(contactInfo.getIncome()));
            ls.add(contactInfoRes);
        }
        return ls;
    }

    @Override
    public void customerGroupInfoUpdate(ModifyCustomerGroupReq req) throws TxnBizException {
        try {
            //查询并验证客户是否存在
            CmCustomerSecondLevel secondLevel = getSecondLevelByCondition(req.getUserId(), req.getChannel(), req.getTenantId(), null);
            //构建要修改的客户信息
            CmCustomerSecondLevel modifySecondLevel = new CmCustomerSecondLevel();
            modifySecondLevel.setId(secondLevel.getId());
            modifySecondLevel.setCustomerId(secondLevel.getCustomerId());
            modifySecondLevel.setTenantId(secondLevel.getTenantId());
            modifySecondLevel.setCustomerGroup(req.getCustomerGroup());
            modifySecondLevel.setUpdateBy(req.getUserId());
            //构建修改历史记录bean
            HistoryLog txnHistoryLog = new HistoryLog(secondLevel.getCustomerId(), req.getTenantId(),
                    secondLevel.getOrganizationId(),
                    secondLevel.getChannel(), req.getUserId(), CustomerMaintenanceType.CUSTOMER_GROUP.getCode());
            txnHistoryLog.setAlterReason(req.getAlterReason());
            HistoryLogHelper.setLocalHistory(txnHistoryLog);
            logger.info("原customerGroup:{},修改为:{}",secondLevel.getCustomerGroup(),req.getCustomerGroup());
            //修改客群
            int count = extCmCustomerSecondLevelMapper.updateByIdAndCustomerIdAndTenantId(modifySecondLevel);
            //没有修改成功
            if (count != 1) {
                String errMsg = String.format(ErrorMsgConstant.MODIFY_CUSTOMER_GROUP_ERROR, req.getUserId());
                logger.info(errMsg);
            }
            if(StringUtils.isNotBlank(req.getCustomerLevel())){
                CmCustomerFirstLevel customerFirstLevel = getFirstLevelByCondition(secondLevel.getCustomerId(),secondLevel.getOrganizationId(),secondLevel.getTenantId());
                logger.info("原customerLevel:{},修改为:{}",customerFirstLevel.getCustomerLevel(),req.getCustomerLevel());
                CmCustomerFirstLevel updateFirstLevel = new CmCustomerFirstLevel();
                updateFirstLevel.setId(customerFirstLevel.getId());
                updateFirstLevel.setCustomerId(customerFirstLevel.getCustomerId());
                updateFirstLevel.setTenantId(customerFirstLevel.getTenantId());
                updateFirstLevel.setCustomerLevel(req.getCustomerLevel());
                extCmCustomerFirstLevelMapper.updateByIdAndCustomerIdAndTenantId(updateFirstLevel);
            }

        } finally {
            HistoryLogHelper.clearLocalHistory();
        }
    }

    @Override
    public List<CustomerPageRes> getCustomerList(String mobile, String idNo, String tenantId, String name, String userId, String customerId) throws TxnBizException {

        if (StringUtils.isNotBlank(mobile) || StringUtils.isNotBlank(userId)) {
            //根据手机号 租户id查询客户二级表信息
            //当用手机号查询时 以二级表为准
            List<CmCustomerSecondLevel> cmCustomerSecondLevels = extCmCustomerSecondLevelMapper.selectCustomerSecondLevelByTenanIdAndMobile(mobile, tenantId, userId);
            //判断客户二级表是否存在
            if (cmCustomerSecondLevels.isEmpty()) {
                throw new TxnBizException(TxnRespCode.NO_DATA.getCode(), TxnRespCode.NO_DATA.getMsg());
            }
            //获取客户二级表中客户id集合
            List<String> customerIdList = cmCustomerSecondLevels.stream().map(CmCustomerSecondLevel::getCustomerId).collect(Collectors.toList());
            //根据客户id集合和租户id查询客户一级表
            List<CmCustomerFirstLevel> cmCustomerFirstLevelList = extCmCustomerFirstLevelMapper.selectFirstLevelByTentanIdAndCusIds(tenantId, customerIdList);
            //转成<客户id,CmCustomerFirstLevel>的map
            Map<String, CmCustomerFirstLevel> customerFirstMap = cmCustomerFirstLevelList.stream().collect(Collectors.toMap(CmCustomerFirstLevel::getCustomerId, cmCustomerFirstLevel -> cmCustomerFirstLevel));
            //将客户二级表信息赋值给返回集合
            List<CustomerPageRes> customerPageResList = BeanMapping.copyList(cmCustomerSecondLevels, CustomerPageRes.class);

            // 声明赋值规则
            Consumer<CustomerPageRes> consumer = customerPageRes -> {
                //根据客户id获取客户一级表信息
                CmCustomerFirstLevel cmCustomerFirstLevel = customerFirstMap.get(customerPageRes.getCustomerId());
                //证件类型
                customerPageRes.setIdType(cmCustomerFirstLevel.getIdType());
                //证件号
                customerPageRes.setIdNumber(cmCustomerFirstLevel.getIdNumber());
                //发证机关
                customerPageRes.setIdIssueAgent(cmCustomerFirstLevel.getIdIssueAgent());
                //中文名称
                customerPageRes.setChineseName(cmCustomerFirstLevel.getChineseName());
                //机构号
                customerPageRes.setOrgId(cmCustomerFirstLevel.getOrganizationId());
                //性别
                customerPageRes.setSex(cmCustomerFirstLevel.getSex());
                customerPageRes.setEcifId(cmCustomerFirstLevel.getEcifId());
            };
            //根据自定义规则 将一级表信息 赋值给返回对象
            customerPageResList.forEach(consumer);
            //返回结果
            return customerPageResList;
        } else if (StringUtils.isNotBlank(idNo) || StringUtils.isNotBlank(name) || StringUtils.isNotBlank(customerId)) {
            //当用证件号查询时 以一级表为准
            //根据租户id和证件号,或姓名，或customerId查询客户一级表信息,
            List<CmCustomerFirstLevel> cmCustomerFirstLevelList = extCmCustomerFirstLevelMapper.selectFirstLevelByTentanIdAndIdNumber(tenantId, idNo, name, customerId);
            //判断客户一级表信息是否存在
            if (cmCustomerFirstLevelList == null || cmCustomerFirstLevelList.isEmpty()) {
                throw new TxnBizException(TxnRespCode.NO_DATA.getCode(), TxnRespCode.NO_DATA.getMsg());
            }
            //转成<客户id,CmCustomerFirstLevel>的map
            Map<String, CmCustomerFirstLevel> customerFirstMap = cmCustomerFirstLevelList.stream().collect(Collectors.toMap(CmCustomerFirstLevel::getCustomerId, cmCustomerFirstLevel -> cmCustomerFirstLevel));

            //获取客户二级表中客户id集合
            List<String> customerIdList = cmCustomerFirstLevelList.stream().map(CmCustomerFirstLevel::getCustomerId).collect(Collectors.toList());
            //根据客户id，租户id查询客户二级表信息
            List<CmCustomerSecondLevel> cmCustomerSecondLevels = extCmCustomerSecondLevelMapper.selectCustomerSecondLevelByTenanIdAndCustomerIdList(tenantId, customerIdList);
            // 声明赋值规则
            Consumer<CustomerPageRes> consumer = customerPageRes -> {
                //根据客户id获取客户一级表信息
                CmCustomerFirstLevel cmCustomerFirstLevel = customerFirstMap.get(customerPageRes.getCustomerId());
                //证件类型
                customerPageRes.setIdType(cmCustomerFirstLevel.getIdType());
                //证件号
                customerPageRes.setIdNumber(cmCustomerFirstLevel.getIdNumber());
                //发证机关
                customerPageRes.setIdIssueAgent(cmCustomerFirstLevel.getIdIssueAgent());
                //中文名称
                customerPageRes.setChineseName(cmCustomerFirstLevel.getChineseName());
                //机构号
                customerPageRes.setOrgId(cmCustomerFirstLevel.getOrganizationId());
                //性别
                customerPageRes.setSex(cmCustomerFirstLevel.getSex());
                customerPageRes.setEcifId(cmCustomerFirstLevel.getEcifId());
            };
            //将客户二级表信息 赋值给返回对象
            List<CustomerPageRes> customerPageResList = BeanMapping.copyList(cmCustomerSecondLevels, CustomerPageRes.class);
            //根据自定义规则 将一级表信息 赋值给返回对象
            customerPageResList.forEach(consumer);
            //返回结果
            return customerPageResList;
        } else {
            throw new TxnBizException(TxnRespCode.NO_DATA.getCode(), TxnRespCode.NO_DATA.getMsg());
        }
    }

    @Override
    public List<CmCustomerFirstLevel> getCustomerList(String mobile, String idNo, String tenantId) throws TxnBizException {

        if(StringUtils.isNotBlank(mobile)){
            //当用手机号查询时 以二级表为准
            List<CmCustomerSecondLevel> cmCustomerSecondLevels =
                    extCmCustomerSecondLevelMapper.selectCustomerSecondLevelByTenanIdAndMobile(mobile, tenantId, null);
            //判断客户二级表是否存在
            if (cmCustomerSecondLevels.isEmpty()) {
                throw new TxnBizException(TxnRespCode.NO_DATA.getCode(), TxnRespCode.NO_DATA.getMsg());
            }
            //获取客户二级表中客户id集合
            List<String> customerIdList = cmCustomerSecondLevels.stream().map(CmCustomerSecondLevel::getCustomerId).collect(Collectors.toList());
            //根据客户id集合和租户id查询客户一级表
            List<CmCustomerFirstLevel> cmCustomerFirstLevelList = extCmCustomerFirstLevelMapper.selectFirstLevelByTentanIdAndCusIds(tenantId, customerIdList);

            //返回结果
            return cmCustomerFirstLevelList;
        }else{
            List<CmCustomerFirstLevel> cmCustomerFirstLevelList =
                    extCmCustomerFirstLevelMapper.selectFirstLevelByTentanIdAndIdNumber(tenantId, idNo, null,
                            null);
            //判断客户一级表信息是否存在
            if (cmCustomerFirstLevelList == null || cmCustomerFirstLevelList.isEmpty()) {
                throw new TxnBizException(TxnRespCode.NO_DATA.getCode(), TxnRespCode.NO_DATA.getMsg());
            }
            return cmCustomerFirstLevelList;
        }
    }

    @Override
    public ArrayList<ContactInfoRes> getContactList(String channel, String customerId, String tenantId) {
        CmCustomerContactInfo cond = new CmCustomerContactInfo();
        cond.setChannel(channel);
        cond.setCustomerId(customerId);
        cond.setContactStatus(CustomerConstant.STATUS_NORMAL);
        cond.setTenantId(tenantId);
        List<CmCustomerContactInfo> ls = extCmCustomerContactInfoMapper.selectByCondSelective(cond);
        List<ContactInfoRes> res = parse(ls);
        return (ArrayList<ContactInfoRes>) res;
    }

    @Override
    public ArrayList<AddressInfoRes> getAddressList(String channel, String customerId, String tenantId) {
        //获取二级表信息的家庭电话
        CmCustomerSecondLevel secondLevel = extCmCustomerSecondLevelMapper.selectByCustomerIdAndChannel(customerId,channel,tenantId);
        CmCustomerAddressInfo cond = new CmCustomerAddressInfo();
        cond.setAddressStatus(CustomerConstant.STATUS_NORMAL);
        cond.setCustomerId(customerId);
        cond.setChannel(channel);
        cond.setTenantId(tenantId);
        List<CmCustomerAddressInfo> ls = extCmCustomerAddressInfoMapper.selectByCondSelective(cond);
        List<AddressInfoRes> res = BeanMapping.copyList(ls, AddressInfoRes.class);
        for (AddressInfoRes addressInfo:res ) {
            addressInfo.setHomePhone(secondLevel.getHomePhone());
        }
        return (ArrayList<AddressInfoRes>) res;
    }

    @Override
    public ArrayList<CompanyInfoRes> getCompanyList(String channel, String customerId, String tenantId) {
        ArrayList<CompanyInfoRes> companyInfoResArrayList=new ArrayList<>();
        CmCustomerSecondLevel secondLevelCond = new CmCustomerSecondLevel();
        secondLevelCond.setChannel(channel);
        secondLevelCond.setCustomerId(customerId);
        secondLevelCond.setTenantId(tenantId);
        List<CmCustomerSecondLevel> secondLevels = extCmCustomerSecondLevelMapper.selectByCondition(secondLevelCond);
        for (CmCustomerSecondLevel second : secondLevels) {
            //获取该用户有效的单位地址信息
            CmCustomerAddressInfo cond = new CmCustomerAddressInfo();
            cond.setAddressStatus(CustomerConstant.CUSTOMER_LIMIT_TYPE_3);
            cond.setCustomerId(customerId);
            cond.setChannel(channel);
            cond.setTenantId(tenantId);
            cond.setAddressStatus(CustomerConstant.CREDIT_LIMIT_STATUS_1);
            List<CmCustomerAddressInfo> ls = extCmCustomerAddressInfoMapper.selectByCondSelective(cond);

            CompanyInfoRes companyInfoRes = new CompanyInfoRes();
            companyInfoRes.setCompanyName(second.getCompanyName());
            companyInfoRes.setCompanyAttribute(second.getCompanyAttribute());
            companyInfoRes.setCompanyPhone(second.getCompanyPhone());
            CmCustomerAddressInfo customerAddressInfo=ls.stream().filter(address->address.getAddressType().equals("3")).findAny().orElse(null);
            if(customerAddressInfo!=null){
                companyInfoRes.setCity(customerAddressInfo.getCity());
                companyInfoRes.setDistrict(customerAddressInfo.getDistrict());
                companyInfoRes.setProvince(customerAddressInfo.getProvince());
                companyInfoRes.setAddress(customerAddressInfo.getAddress());
            }
            companyInfoResArrayList.add(companyInfoRes);
        }

        return companyInfoResArrayList;
    }

    @Override
    public CustomerFirstLevelRes getCustomerByOrgIdAndIdCard(String idNumber, String idType, String organizationId, String tenantId) throws TxnException {
        CacheMapping cacheMapping = cacheMappingService.selectFromCacheByIdNumber(tenantId, idNumber,true);
        if (cacheMapping == null) {
            throw new TxnBizException(TxnRespCode.NO_DATA.getCode(), TxnRespCode.NO_DATA.getMsg());
        }
        String customerId = cacheMapping.getCustomerId();
        CmCustomerFirstLevel cmCustomerFirstLevel = extCmCustomerFirstLevelMapper.selectFirstLevelByOrgIdAndId(idNumber, idType, organizationId, tenantId, customerId);
        if (null == cmCustomerFirstLevel) {
            logger.error(ErrorMsgConstant.CUSTOMER_FIRST_NODATA_BYID);
            throw new TxnException(TxnRespCode.BIZ_ERROR, TxnRespCode.BIZ_ERROR.getUserTips());
        }
        return BeanMapping.copy(cmCustomerFirstLevel, CustomerFirstLevelRes.class);
    }

    @Override
    public CustomerFirstLevelRes getFirstLevelByOrgIdAndCusId(String customerId, String organizationId, String tenantId) throws TxnException {
        CmCustomerFirstLevel cmCustomerFirstLevel = extCmCustomerFirstLevelMapper.selectFirstLevelByOrgIdAndCusId(customerId, organizationId, tenantId);
        if (null == cmCustomerFirstLevel) {
            logger.error(ErrorMsgConstant.CUSTOMER_FIRST_NODATA_BYCUSID);
            throw new TxnException(TxnRespCode.BIZ_ERROR, TxnRespCode.BIZ_ERROR.getUserTips());
        }
        return BeanMapping.copy(cmCustomerFirstLevel, CustomerFirstLevelRes.class);
    }

    @Override
    public CustomerRes getCustomerByChannelAndCustomerIdAndTensnId(String channel, String customerId, String tenantId) throws TxnBizException {
        CmCustomerSecondLevel secondLevelCond = new CmCustomerSecondLevel();
        secondLevelCond.setChannel(channel);
        secondLevelCond.setCustomerId(customerId);
        secondLevelCond.setTenantId(tenantId);
        List<CmCustomerSecondLevel> secondLevels = extCmCustomerSecondLevelMapper.selectByCondition(secondLevelCond);

        if (secondLevels == null || secondLevels.isEmpty()) {
            logger.error("获取客户信息时客户二级信息不存在");
            throw new TxnBizException(TxnRespCode.NO_DATA.getCode(), TxnRespCode.NO_DATA.getMsg());
        } else if (secondLevels.size() > 1) {
            logger.error(ErrorMsgConstant.UNIQUE_SECORD_CUSTOMER);
            throw new TxnBizException(TxnRespCode.BIZ_ERROR.getCode(), TxnRespCode.BIZ_ERROR.getUserTips());
        }
        CmCustomerSecondLevel secondLevel = secondLevels.get(0);
        if (secondLevel == null) {
            logger.error("获取客户信息时客户二级信息不存在");
            throw new TxnBizException(TxnRespCode.NO_DATA.getCode(), TxnRespCode.NO_DATA.getMsg());
        }
        CmCustomerFirstLevel firstLevel = this.getFirstLevelByCondition(customerId, secondLevel.getOrganizationId(), tenantId);
        if (firstLevel == null) {
            logger.error("获取客户信息时客户一级信息不存在");
            throw new TxnBizException(TxnRespCode.NO_DATA.getCode(), TxnRespCode.NO_DATA.getMsg());
        }
        CustomerRes res = new CustomerRes();
        res.setFirstLevel(BeanMapping.copy(firstLevel, CustomerFirstLevelRes.class));
        res.setSecondLevel(BeanMapping.copy(secondLevel, CustomerSecondLevelRes.class));
        return res;
    }

    @Override
    public CmCustomerSecondLevel getSecondByChannelAndCustomerIdAndTensnId(String channel, String customerId, String tenantId, String productId) throws TxnBizException {
        CmCustomerSecondLevel secondLevelCond = new CmCustomerSecondLevel();
        secondLevelCond.setChannel(channel);
        secondLevelCond.setCustomerId(customerId);
        secondLevelCond.setTenantId(tenantId);
        List<CmCustomerSecondLevel> secondLevels = extCmCustomerSecondLevelMapper.selectByCondition(secondLevelCond);
        //判断客户id在该渠道下是否有数据
        if (secondLevels == null || secondLevels.isEmpty()) {
            return null;
        }
        if (secondLevels.size() > 1) {
            logger.error(ErrorMsgConstant.UNIQUE_SECORD_CUSTOMER);
            throw new TxnBizException(TxnRespCode.BIZ_ERROR.getCode(), TxnRespCode.BIZ_ERROR.getUserTips());
        }
        CmCustomerSecondLevel secondLevel = setOrgAndMgrNo(tenantId, productId, secondLevels);
        return secondLevel;
    }

    /**
     * 设置客户经理编号和分支行编号
     * @param tenantId
     * @param productId
     * @param secondLevels
     * @return
     */
    public CmCustomerSecondLevel setOrgAndMgrNo(String tenantId, String productId, List<CmCustomerSecondLevel> secondLevels) {
        CmCustomerSecondLevel secondLevel = secondLevels.get(0);
        if (StringUtils.isNotBlank(productId)) {
            List<CmCustomerExtInfo> cmCustomerExtInfos = extCmCustomerExtInfoMapper.queryCustomerExtInfos(secondLevel.getCustomerId(), tenantId, BizTypeProducts.getSymbolProductId(productId));
            // 设置内部机构号
            String bankOrgNo = secondLevel.getBankOrgNo();
            String bankMgrNo = secondLevel.getBankMgrNo();
            if (!CollectionUtils.isEmpty(cmCustomerExtInfos) && StringUtils.isNotBlank(cmCustomerExtInfos.get(0).getBankOrgNo())) {
                //获取客户二级信息所属机构号
                bankOrgNo = cmCustomerExtInfos.get(0).getBankOrgNo();
            }
            if (!CollectionUtils.isEmpty(cmCustomerExtInfos) && StringUtils.isNotBlank(cmCustomerExtInfos.get(0).getBankMgrNo())) {
                //获取客户二级信息客户经理编号
                bankMgrNo = cmCustomerExtInfos.get(0).getBankMgrNo();
            }
            secondLevel.setBankOrgNo(bankOrgNo);
            secondLevel.setBankMgrNo(bankMgrNo);
        }
        return secondLevel;
    }


    @Override
    public List<CmCustomerSecondLevel> getSecondByCustomerIdAndTensnId( String customerId, String tenantId) throws TxnBizException {
        CmCustomerSecondLevel secondLevelCond = new CmCustomerSecondLevel();
        secondLevelCond.setCustomerId(customerId);
        secondLevelCond.setTenantId(tenantId);
        List<CmCustomerSecondLevel> secondLevels = extCmCustomerSecondLevelMapper.selectByCondition(secondLevelCond);
        return secondLevels;
    }

    @Override
    public ArrayList<CustomerWholeInfoRes> getIdentityByChannelAndCustomerIdAndTenId(String channel, String customerId, String tenantId) throws TxnBizException{
        CustomerRes res = getCustomerByChannelAndCustomerIdAndTensnId(channel, customerId, tenantId);
        ArrayList<CustomerWholeInfoRes> customerWholeInfoResArrayList=new ArrayList<>();
        CustomerWholeInfoRes customerWholeInfoRes=new CustomerWholeInfoRes();
        //学历
        customerWholeInfoRes.setEducation(res.getSecondLevel().getEducation());
        //出生日期
        customerWholeInfoRes.setBirthDate(DateUtils.format(res.getFirstLevel().getBirthDate()));
        //证件有效其实日期
        customerWholeInfoRes.setIdEffectiveDate(res.getFirstLevel().getIdEffectiveDate());
        //证件有效终止日期
        customerWholeInfoRes.setIdExpireDate(res.getFirstLevel().getIdExpireDate());
        //已婚状态
        customerWholeInfoRes.setMaritalStatus(res.getSecondLevel().getMaritalStatus());
        //民族
        customerWholeInfoRes.setRace(res.getFirstLevel().getRace());
        //发证机关
        customerWholeInfoRes.setIdIssueAgent(res.getFirstLevel().getIdIssueAgent());
        customerWholeInfoResArrayList.add(customerWholeInfoRes);
        return customerWholeInfoResArrayList;
    }

    @Override
    public void customerGroupInfoUpdateByCms( String customerId, String channel,String tenantId,String customerGroup, String alterReason) throws TxnBizException {
        try {
            //查询并验证客户是否存在
            CmCustomerSecondLevel secondLevel = getSecondByChannelAndCustomerIdAndTensnId(channel,customerId ,tenantId, null);
            //构建要修改的客户信息
            CmCustomerSecondLevel modifySecondLevel = new CmCustomerSecondLevel();
            modifySecondLevel.setId(secondLevel.getId());
            modifySecondLevel.setCustomerId(secondLevel.getCustomerId());
            modifySecondLevel.setTenantId(secondLevel.getTenantId());
            modifySecondLevel.setCustomerGroup(customerGroup);
            modifySecondLevel.setUpdateBy(secondLevel.getUserId());
            //构建修改历史记录bean
            HistoryLog txnHistoryLog = new HistoryLog(secondLevel.getCustomerId(), tenantId,
                    secondLevel.getOrganizationId(),
                    secondLevel.getChannel(), secondLevel.getUserId(), CustomerMaintenanceType.CUSTOMER_GROUP.getCode());
            txnHistoryLog.setAlterReason(alterReason);
            HistoryLogHelper.setLocalHistory(txnHistoryLog);
            //修改客群
            int count = extCmCustomerSecondLevelMapper.updateByIdAndCustomerIdAndTenantId(modifySecondLevel);
            //没有修改成功
            if (count != 1) {
                String errMsg = String.format(ErrorMsgConstant.MODIFY_CUSTOMER_GROUP_ERROR, secondLevel.getUserId());
                logger.error(errMsg);
                throw new TxnBizException(TxnRespCode.BIZ_ERROR.getCode(), TxnRespCode.BIZ_ERROR.getUserTips());
            }
        } finally {
            HistoryLogHelper.clearLocalHistory();
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void customerMobileUpdate(String userId,String tenantId,String channel ,String mobile) throws Exception {
        try {
            //查询并验证客户是否存在
            CmCustomerSecondLevel secondLevel = getSecondLevelByCondition(userId, channel, tenantId, null);
            CmCustomerFirstLevel firstLevel = getFirstLevelByCondition(secondLevel.getCustomerId(),secondLevel.getOrganizationId(),secondLevel.getTenantId());

            //构建要修改的客户信息
            CmCustomerSecondLevel modifySecondLevel = new CmCustomerSecondLevel();
            modifySecondLevel.setId(secondLevel.getId());
            modifySecondLevel.setCustomerId(secondLevel.getCustomerId());
            modifySecondLevel.setTenantId(secondLevel.getTenantId());
            modifySecondLevel.setMobile(mobile);
            modifySecondLevel.setUpdateBy(userId);
            //构建修改历史记录bean
            HistoryLog txnHistoryLog = new HistoryLog(secondLevel.getCustomerId(), tenantId,
                    secondLevel.getOrganizationId(),
                    secondLevel.getChannel(), userId, CustomerMaintenanceType.CUSTOMER_INFO.getCode());
            HistoryLogHelper.setLocalHistory(txnHistoryLog);
            //修改手机号
            int count = extCmCustomerSecondLevelMapper.updateByIdAndCustomerIdAndTenantId(modifySecondLevel);
            //没有修改成功
            if (count != 1) {
                String errMsg = String.format(ErrorMsgConstant.MODIFY_CUSTOMER_MOBILE_ERROR, userId);
                logger.error(errMsg);
                throw new TxnBizException(TxnRespCode.BIZ_ERROR.getCode(), TxnRespCode.BIZ_ERROR.getUserTips());
            }
            UpdateCacheMapping updateCacheMapping = new UpdateCacheMapping();
            updateCacheMapping.setChannel(channel);
            updateCacheMapping.setCustomerId(secondLevel.getCustomerId());
            updateCacheMapping.setIdNumber(firstLevel.getIdNumber());
            updateCacheMapping.setMobile(mobile);
            updateCacheMapping.setOldMobile(secondLevel.getMobile());
            updateCacheMapping.setUserId(secondLevel.getUserId());
            updateCacheMapping.setTenantId(tenantId);
            int result = cacheMappingService.updateMobileAndCache(updateCacheMapping);
            if(result != 1){
                throw new Exception("缓存修改失败");
            }
        } finally {
            HistoryLogHelper.clearLocalHistory();
        }
    }

    /**
     * 保存营销记录
     * @param marketingRecordCreationBean
     * @throws TxnBizException
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public TlMarketingRecord generateMarketingRecord(MarketingRecordCreationBean marketingRecordCreationBean) throws TxnBizException {
        //一级客户信息
        CmCustomerFirstLevel customerFirstLevel = marketingRecordCreationBean.getCustomerFirstLevel();
        //二级客户信息
        CmCustomerSecondLevel customerSecondLevel = marketingRecordCreationBean.getCustomerSecondLevel();
        //客户信息不存在，直接返回
        if(null == customerFirstLevel || null == customerSecondLevel){
            return null;
        }
        if(StringUtils.isEmpty(customerSecondLevel.getOrganizationId())){
            //根据渠道号获取机构ID 判断渠道是否存在渠道不存在---抛出异常结束
            PrChannelTable channelTable = iChannelTableService.getChannelTableByChannelIdAndStatus(CustomerConstant.STATUS_NORMAL, customerSecondLevel.getChannel(), customerSecondLevel.getTenantId());
            customerSecondLevel.setOrganizationId(channelTable.getOrganizationId());
        }

        PrOrganizationTable org = extPrOrganizationTableMapper.selectByOrganizationId(customerSecondLevel.getOrganizationId(), customerSecondLevel.getTenantId());
        TlMarketingRecord marketingRecord = new TlMarketingRecord();
        marketingRecord.setTenantId(customerSecondLevel.getTenantId());
        marketingRecord.setOrganizationId(customerSecondLevel.getOrganizationId());
        marketingRecord.setCustomerId(customerSecondLevel.getCustomerId());
        marketingRecord.setUserId(customerSecondLevel.getUserId());
        marketingRecord.setIdNumber(customerFirstLevel.getIdNumber());
        marketingRecord.setChineseName(customerFirstLevel.getChineseName());
        marketingRecord.setMobile(customerSecondLevel.getMobile());
        marketingRecord.setRecommenderCode(customerSecondLevel.getRecommenderCode());
        marketingRecord.setChannel(customerSecondLevel.getChannel());
        marketingRecord.setStep(marketingRecordCreationBean.getStep());
        marketingRecord.setWorkType(customerSecondLevel.getOccuptionType());
        marketingRecord.setCompanyName(customerSecondLevel.getCompanyName());
//        marketingRecord.setSeqNo(marketingRecordCreationBean.getSeqNo());
        marketingRecord.setSeqNo(SeqUtils.getSNByLength(32));
        marketingRecord.setBusinessDate(org.getNextProcessingDate());
        marketingRecord.setBusinessTime(DateUtils.getBusinessTime(new Date(),org.getNextProcessingDate()));
        marketingRecord.setSumStatus(CustomerConstant.MARKET_SUM_STATUS_T);
        marketingRecord.setRecordVersionNumber(Constant.VERSION_NUMBER);
        marketingRecord.setUpdateBy(customerSecondLevel.getUserId());
        marketingRecord.setGrayVersion(grayVersionConfig.getCurrentVersion());
        //保存地址信息
        if(CollectionUtils.isNotEmpty(marketingRecordCreationBean.getAddressInfoList())){
            for(CmCustomerAddressInfo addressInfo : marketingRecordCreationBean.getAddressInfoList()){
                //居住地址
                if(CustomerConstant.ADDRESS_TYPE_1.equals(addressInfo.getAddressType())){
                    marketingRecord.setLiveProvince(addressInfo.getProvince());
                    marketingRecord.setLiveCity(addressInfo.getCity());
                    marketingRecord.setLiveArea(addressInfo.getDistrict());
                    marketingRecord.setLiveAddress(addressInfo.getAddress());
                }
                // 工作地址
                if(CustomerConstant.ADDRESS_TYPE_3.equals(addressInfo.getAddressType())){
                    marketingRecord.setWorkProvince(addressInfo.getProvince());
                    marketingRecord.setWorkCity(addressInfo.getCity());
                    marketingRecord.setWorkArea(addressInfo.getDistrict());
                    marketingRecord.setWorkAddress(addressInfo.getAddress());
                }
            }
        }
        //保存授信额度
        if(CollectionUtils.isNotEmpty(marketingRecordCreationBean.getCustomerLimitInfoList())){
            CmCustomerLimitInfo fatherLimitInfo = marketingRecordCreationBean.getCustomerLimitInfoList().stream().filter(limitInfo->limitInfo.getFatherId() == null).findAny().orElse(null);
            if(null != fatherLimitInfo){
                marketingRecord.setCreditAmount(fatherLimitInfo.getLimitAmount());
            }
        }
        return marketingRecord;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void customerIdUpdate(CmCustomerFirstLevel customerFirstLevel) throws TxnBizException {
        int count = extCmCustomerFirstLevelMapper.updateByIdAndCustomerIdAndTenantId(customerFirstLevel);
        if (count != 1) {
            throw new TxnBizException(TxnRespCode.BIZ_ERROR.getCode(), TxnRespCode.BIZ_ERROR.getUserTips());
        }
    }

    @Override
    public CmCustomerSecondLevel getSecondByMobileAndTenantId(String mobile, String tenantId) throws TxnBizException {
        List<CmCustomerSecondLevel> cmCustomerSecondLevels = extCmCustomerSecondLevelMapper.getSecondByMobileAndTenantId(mobile, tenantId);
        if (cmCustomerSecondLevels.size() < 1) {
            throw new TxnBizException(TxnRespCode.GET_CUSTOMER_NULL.getCode(), TxnRespCode.GET_CUSTOMER_NULL.getMsg());
        }
        else if (cmCustomerSecondLevels.size() > 1) {
            logger.info("二级客户信息集合："+JSON.toJSONString(cmCustomerSecondLevels));
            throw new TxnBizException(TxnRespCode.GET_CUSTOMER_ERROR.getCode(), TxnRespCode.GET_CUSTOMER_ERROR.getMsg());
        }
        return cmCustomerSecondLevels.get(0);
    }

    /**
     * 补充二类户开户时联网核查
     */
    @Override
    public void internetCheckAgain() {
        // 查询授信和激活时间不在同一天的用户
        List<CmCustomerFirstLevel> list = extCmCustomerSecondLevelMapper.queryCreditActiveNoteEq(Constants.DEFAULT_TENANT_ID);
        if (CollectionUtils.isNotEmpty(list)) {
            list.forEach(fir -> {
                try {
                    CheckRequest06 checkRequest06 = new CheckRequest06();
                    checkRequest06.setIdNo(fir.getIdNumber());
                    checkRequest06.setName(fir.getChineseName());
                    checkRequest06.setBusType("05");
                    checkRequest06.setTenantId(fir.getTenantId());
                    checkRequest06.setServiceId(CustomerConstant.GATEWAY_SERVICE_ID);
                    checkRequest06.setServiceIp(InternetUtils.getLocalIp());
                    checkRequest06.setServiceSeq(SeqUtils.getSN());
                    iUserApiService.internetCheckAgain(JsonUtils.toJSon(checkRequest06));
                    // 2秒钟
                    Thread.sleep(1000 * 2);
                } catch (Exception e) {
                    logger.warn("用户{}补充二类户开户时联网核查失败", fir.getCustomerId());
                    e.printStackTrace();
                }
            });
        }
    }

    @Override
    public void saveEcif(CustomerInfoCreationBean customerOperationBean) throws Exception {
        //处理ecif注册/更新
        String ecifCustId = this.dealEcif(customerOperationBean);
        CmCustomerFirstLevel updateFirst = new CmCustomerFirstLevel();
        //主键
        updateFirst.setId(customerOperationBean.getEcifCmCustomerFirstLevel().getId());;
        //客户id
        updateFirst.setCustomerId(customerOperationBean.getEcifCmCustomerFirstLevel().getCustomerId());
        //租户id
        updateFirst.setTenantId(customerOperationBean.getEcifCmCustomerFirstLevel().getTenantId());
        //修改人
        updateFirst.setUpdateBy(customerOperationBean.getCustomerSupplyReq().getUserId());
        //修改一级客户表
        HistoryLog txnHistoryLog = new HistoryLog(updateFirst.getCustomerId(), updateFirst.getTenantId(), customerOperationBean.getOrgId(), customerOperationBean.getChannel(), updateFirst.getUpdateBy(), CustomerMaintenanceType.CUSTOMER_INFO.getCode());
        HistoryLogHelper.setLocalHistory(txnHistoryLog);
        updateFirst.setEcifId(ecifCustId);
        //存在 执行修改操作
        int firstModify = extCmCustomerFirstLevelMapper.updateByIdAndCustomerIdAndTenantId(updateFirst);
        if (firstModify <= 0) {
            throw new TxnBizException(ErrorMsgConstant.FIRST_CUSTOMER_MODIFY_ERROR);
        }

    }

    /**
     * 客户额外信息补充修改
     *
     * @param req
     */
    @Override
    public CmCustomerExtInfo extInfo(CusExtInfoReq req) throws TxnBizException {
        String userId = req.getUserId();
        String productId = req.getProductId();
        String channel = req.getChannel();
        String tenantId = req.getTenantId();
        CmCustomerExtInfo info = new CmCustomerExtInfo();
        info.setChannel(channel);
        info.setTenantId(tenantId);
        info.setUserId(userId);
        info.setProductId(productId);
        CmCustomerExtInfo res = extCmCustomerExtInfoMapper.selectByConditions(info);
        // 对象为空执行插入
        if (Objects.isNull(res) || Objects.isNull(res.getId())) {
            CmCustomerExtInfo insertInfo = new CmCustomerExtInfo();
            //获取客户二级信息
            CmCustomerSecondLevel secondLevel = getSecondLevelByCondition(userId, channel, tenantId, productId);
            try {
                BeanUtils.copyProperties(req, insertInfo);
                insertInfo.setCustomerId(secondLevel.getCustomerId());
                insertInfo.setOrganizationId(secondLevel.getOrganizationId());
                insertInfo.setSubChannel(secondLevel.getSubChannel());
                insertInfo.setProductActiveFlag(Constants.DISABLED);
                insertInfo.setCustomerStatus(Constants.ENABLED);
                insertInfo.setUpdateBy(Constant.SYS_OPRATE);
                insertInfo.setRecordVersionNumber(1);
                insertInfo.setId(iSegmentService.getId("CmCustomerExtInfo"));
                extCmCustomerExtInfoMapper.insertSelective(insertInfo);
                res = new CmCustomerExtInfo();
                BeanUtils.copyProperties(insertInfo, res);
            } catch (SegmentException e) {
                logger.error("主键生成错误",e);
                throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
            }
        } else {
            // 更新
            res.setId(res.getId());
            res.setTenantId(tenantId);
            res.setProductActiveFlag(req.getProductActiveFlag());
            res.setUpdateBy(Constant.SYS_OPRATE);
            if (StringUtils.isBlank(res.getBankOrgNo())) {
                res.setBankOrgNo(req.getBankOrgNo());
            }
            if (StringUtils.isBlank(res.getBankMgrNo())) {
                res.setBankMgrNo(req.getBankMgrNo());
            }
            res.setRecordVersionNumber(res.getRecordVersionNumber() + 1);
            extCmCustomerExtInfoMapper.updateProductActiveFlag(res);
        }
        return res;
    }

    /**
     * 客户基础信息查询
     * 信息包含：核心客编、开户行、客户经理
     *
     * @param req
     * @return
     */
    @Override
    public CustomerBaseInfoRes customerBaseInfoQuery(BaseApiReq req) throws TxnBizException {
        CustomerBaseInfoRes res = new CustomerBaseInfoRes();
        //获取客户二级信息
        CmCustomerSecondLevel secondLevel = getSecondLevelByCondition(req.getUserId(), req.getChannel(), req.getTenantId(), null);
        //获取客户一级信息
        CmCustomerFirstLevel firstLevel = getFirstLevelByCondition(secondLevel.getCustomerId(),
                secondLevel.getOrganizationId(), secondLevel.getTenantId());

        res.setUserId(secondLevel.getUserId());
        res.setSeqNo(req.getSeqNo());
        res.setEcifId(firstLevel.getEcifId());
        res.setBankMgrNo(secondLevel.getBankMgrNo());
        res.setBankOrgNo(secondLevel.getBankOrgNo());

        return res;
    }

    /**
     * 根据客户id修改客户手机号
     *
     * @param req
     * @return
     */
    @Override
    public void customerMobileUpdateByCms(CustomerMobileUpdateByCmsReq req) throws TxnBizException {
        CmCustomerSecondLevel secondLevelQueryReq = new CmCustomerSecondLevel();
        secondLevelQueryReq.setCustomerId(req.getCustomerId());
        secondLevelQueryReq.setTenantId(req.getTenantId());
        secondLevelQueryReq.setChannel(req.getChannel());

        //获取客户二级信息
        CmCustomerSecondLevel secondLevel = extCmCustomerSecondLevelMapper.selectByCondition(secondLevelQueryReq)
                .stream().findAny().orElseThrow(() -> new TxnBizException(TxnRespCode.CUSTOMER_INFO_NOT_EXIST));
        ApiResponse apiResponse = null;
        try {
            PhoneModifyReq phoneModifyReq = new PhoneModifyReq();
            phoneModifyReq.setTenantId(secondLevel.getTenantId());
            phoneModifyReq.setChannelNo(secondLevel.getChannel());
            phoneModifyReq.setUserId(secondLevel.getUserId());
            phoneModifyReq.setMobileNo(req.getMobile());
            apiResponse = iUserApiService.phoneModify(JsonUtils.toJSon(phoneModifyReq));
        } catch (Exception e) {
            e.printStackTrace();
            throw new TxnBizException(TxnRespCode.MOBILE_MODIFY_ERROR);
        }

        if (apiResponse == null) {
            throw new TxnBizException(TxnRespCode.MOBILE_MODIFY_ERROR);
        }

        if (TxnRespCode.SUCCESS.getCode() != apiResponse.getCode()) {
            String errorMsg = null == apiResponse.getMessage() ? TxnRespCode.MOBILE_MODIFY_ERROR.getMsg() : apiResponse.getMessage();
            throw new TxnBizException(errorMsg);
        }

        //构建修改历史记录bean
        HistoryLog txnHistoryLog = new HistoryLog(secondLevel.getCustomerId(), req.getTenantId(),
                secondLevel.getOrganizationId(),
                secondLevel.getChannel(), secondLevel.getUserId(), CustomerMaintenanceType.CUSTOMER_MOBILE.getCode());
        txnHistoryLog.setAlterReason(req.getAlterReason());
        HistoryLogHelper.setLocalHistory(txnHistoryLog);
    }
}
